<?php

namespace App\Library\Service;

use App\Library\Logic\AddressLogic;
use App\Library\Logic\HelpLogic;
use App\Library\Logic\HelpRecordLogic;
use App\Library\Logic\PaymentRelatedLogic;
use App\Library\Logic\ProductSpecLogic;
use App\Library\Logic\ShopOrderExtLogic;
use App\Library\Logic\ShopOrderGoodsLogic;
use App\Library\Logic\ShopOrderLogic;
use App\Library\Logic\ShopProductLogic;
use App\Library\Logic\ShopProductSpecsLogic;
use App\Library\Requests\Base\SerialNumberRequest;
use App\Library\Requests\Base\ShopProductSpecNumberRequest;
use App\Library\Requests\Help\HelpPageRequest;
use App\Library\Requests\Help\HelpOrderRequest;
use App\Library\Service\Payment\WechatService;
use App\Library\YsdLib;
use App\Models\SystemConfigModel;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Arr;
use Yansongda\Pay\Pay;

class HelpService extends BaseService
{
    private int $period;

    public function __construct(HelpLogic $logic)
    {
        $this->logic = $logic;
        $config = SystemConfigModel::query()->where('id',1)->value('content');
        $this->period = Arr::get($config, 'plugValidityTime');
    }

    /**
     * create
     * @param ShopProductSpecNumberRequest $request
     * @return JsonResponse
     */
    public function create(ShopProductSpecNumberRequest $request): JsonResponse
    {
        $specId = cache('shopProductSpec:' . $request->serialNumber);
        $where = ['specId' => $specId, 'userId' => USERID];
        $help = $this->logic->findByWhere($where);
        if (!is_null($help) && now()->lt(now()->parse($help->created_at)->addSeconds($this->period))) {
            return success($help);
        }
        $shopProductSpec = ShopProductSpecsLogic::detail($specId, ['productId', 'ps_price_underlined']);
        if (is_null($shopProductSpec) || $shopProductSpec->product_id === 0) return fail(422);
        else return success(HelpLogic::insertForModel(array_merge($where, [
            'productId' => $shopProductSpec->product_id,
            'amount' => bcmul($shopProductSpec->ps_price_underlined, 100),
        ])));
    }

    /**
     * get
     * @param ShopProductSpecNumberRequest $request
     * @return JsonResponse
     */
    public function get(ShopProductSpecNumberRequest $request): JsonResponse
    {
        $help = $this->logic->findByWhere([
            'specId' => cache('shopProductSpec:' . $request->serialNumber),
            'userId' => USERID,
            'orderByDesc' => null,
        ]);
        if (is_null($help) || now()->gte(now()->parse($help->created_at)->addSeconds($this->period))) return success();
        else return success($help);
    }

    /**
     * cut
     * @param SerialNumberRequest $request
     * @return JsonResponse
     */
    public function cut(SerialNumberRequest $request): JsonResponse
    {
        $help = $this->logic->findBySerialNumber($request);
        if (is_null($help) || $help->user_id === USERID) return fail(422);
        else if (now()->gte(now()->parse($help->created_at)->addSeconds($this->period))) {
            return failMessage('助力已经过期');
        }
        $where = ['helpId' => $help->id, 'userId' => USERID];
        if (HelpRecordLogic::existsByWhere($where)) return failMessage('已经助力过了');
        $helpRecord = HelpRecordLogic::insertForModel(array_merge($where, ['amount' => 1]));
        $help->amount -= $helpRecord->amount;
        $help->save();
        return success($helpRecord->amount);
    }

    /**
     * recordPaging
     * @param HelpPageRequest $request
     * @return JsonResponse
     */
    public function recordPaging(HelpPageRequest $request): JsonResponse
    {
        return success(HelpRecordLogic::recordPaging($request));
    }

    /**
     * order
     * @param HelpOrderRequest $request
     * @return JsonResponse
     * @throws Exception|GuzzleException
     */
    public function order(HelpOrderRequest $request): JsonResponse
    {
        $address = AddressLogic::detail($request->addressId);
        if (is_null($address) || $address->user_id !== USERID) return fail(422);
        $help = $this->logic->findBySerialNumber($request);
        if (is_null($help) || $help->user_id !== USERID) return fail(422);
        else if (now()->gte(now()->parse($help->created_at)->addSeconds($this->period))) {
            return failMessage('助力已经过期');
        }
        $spec = ShopProductSpecsLogic::detail($help->spec_id);
        if (is_null($spec)) return fail(422);
        $product = ShopProductLogic::detail($help->product_id);
        if (is_null($product)) return fail(422);
        else if ($product->product_status !== 2) return failMessage('商品已下架');
        else if ($product->product_stock_empty !== 1 || $spec->ps_total_stock !== 1 || $spec->ps_usable_stock !== 1) {
            return failMessage('库存不足');
        }
        $price = bcdiv($help->amount, 100, 2);
        $order = ShopOrderLogic::insertForModel([
            'help' => 1,
            'buyUserId' => USERID,
            'sellUserId' => $product->user_id,
            'payPrice' => $price,
            'orderTotalPrice' => $price,
            'orderTotalRealPrice' => $price,
            'orderContacts' => $address->contacts,
            'orderContactsMobile' => $address->mobile,
            'orderContactsAddress' => $address->full_address,
            'orderAddTime' => time(),
            'orderNote' => $request->remark,
        ]);
        mq('productOrderCancel', $order->serial_number, (int)__('base.cancelTtl'));
        ShopOrderExtLogic::add($order, 0, $address->id);
        ShopOrderGoodsLogic::plug($product, $spec, $order);
        ProductSpecLogic::decStock([[
            'quantity' => 1,
            'specId' => $spec->ps_id,
            'productId' => $product->product_id,
            'psUsableStock' => $spec->ps_usable_stock
        ]]);
        Pay::config(YsdLib::config());
        $order->title = '异宠星球';
        $paymentRelated = PaymentRelatedLogic::addByProductOrder($order);
        return WechatService::mini($order, $paymentRelated->serial_number, $request->code);
    }
}
